package com.pwt.service;

import com.pwt.common.ResultPage;
import com.pwt.entity.*;
import com.pwt.enu.MenuEnum;
import com.pwt.model.ComboBoxModel;
import com.pwt.model.MachineManageModel;
import com.pwt.model.MenuType;
import com.pwt.model.TreeModel;
import com.pwt.repository.MASCHINERepository;
import com.pwt.repository.MenuSettingRepository;
import com.pwt.repository.RoleRepository;
import com.pwt.security.utils.JWTUtils;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * MenuSetting service层
 *
 * @author auto generated
 * @date 2021-09-28 11:38:50
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class MenuSettingService {

    private MenuSettingRepository menuSettingRepository;

    private RoleRepository roleRepository;

    private MASCHINERepository maschineRepository;

    private JPAQueryFactory jpaQueryFactory;

    public MenuSettingService(MenuSettingRepository menuSettingRepository, RoleRepository roleRepository, MASCHINERepository maschineRepository, JPAQueryFactory jpaQueryFactory) {
        this.menuSettingRepository = menuSettingRepository;
        this.roleRepository = roleRepository;
        this.maschineRepository = maschineRepository;
        this.jpaQueryFactory = jpaQueryFactory;
    }

    public List<MenuType> getMenuType(Integer type){
        List<MenuType> list = new ArrayList<>();
        for (MenuEnum menuEnum:
             MenuEnum.values()) {
            if(menuEnum.getType() == type){
                MenuType menuType = new MenuType();
                menuType.setName(menuEnum.getName());
                menuType.setValue(menuEnum.getValue());
                list.add(menuType);
            }
        }
        return list;
    }


    public List<TreeModel>  getProcess(){

        String username = JWTUtils.getToken().getUsername();
        Set<Role> roles = roleRepository.findByUsername(username);
        QRoleMachine qRoleMachine = QRoleMachine.roleMachine;
        QMASCHINE qMachine = QMASCHINE.mASCHINE;
        HashSet<Integer> list = new HashSet<>();
        for (Role r:roles) {
            List<Integer> maschineList = jpaQueryFactory.select(qMachine.mAMASCHINE).from(qRoleMachine).leftJoin(qMachine).on(qRoleMachine.machineId.eq(qMachine.mAMASCHINE))
                    .where(qRoleMachine.roleId.eq(r.getId())).fetch();
            list.addAll(maschineList);
        }
        List<MachineManageModel> machineList= this.maschineRepository.queryMachineByMachineIds(list);
        HashSet<Integer> prueferSet= new HashSet<>();
        for (MachineManageModel machineManageModel:machineList) {
            prueferSet.add(machineManageModel.getPId());
        }

        List<TreeModel> oneList = new ArrayList<>();
        for (Integer pId:prueferSet) {
            List<TreeModel> twoList = new ArrayList<>();
            TreeModel oneTree = new TreeModel();
            for (MachineManageModel machineManageModel:machineList) {
                if(pId != null && pId.equals(machineManageModel.getPId())){
                    if(oneTree.getId() == null && pId.equals(machineManageModel.getPId())){
                        oneTree.setName(machineManageModel.getPName());
                        oneTree.setId(machineManageModel.getPId());
                        oneTree.setNumber(machineManageModel.getPNumber());
                    }
                }
            }
            oneTree.setChildren(twoList);
            oneList.add(oneTree);
        }

        return oneList;
    }

    public ResultPage<MenuSetting> getMenuSetting(Integer type,String prueferName,Integer page,Integer limit){
        QMenuSetting qMenuSetting = QMenuSetting.menuSetting;
        QPRUEFER qpruefer = QPRUEFER.pRUEFER;

        BooleanBuilder builder = new BooleanBuilder();

        String username = JWTUtils.getToken().getUsername();

        if(type != null){
            builder.and(qMenuSetting.type.eq(type));
        }
        if(prueferName != null){
            builder.and(qpruefer.pRVORNAME.like("%"+prueferName+"%"));
        }
        if(StringUtils.isNotBlank(username)){
            builder.and(qMenuSetting.createBy.eq(username));
        }
        Long count = jpaQueryFactory.select(qMenuSetting.id.count()).from(qMenuSetting)
                .leftJoin(qpruefer).on(qpruefer.pRPRUEFER.eq(qMenuSetting.prueferId))
                .where(builder).fetchOne();
        if (count == null || count == 0) {
            return new ResultPage<MenuSetting>(new ArrayList<>(),page-1,limit, 0L);
        }
        List<MenuSetting>  list = jpaQueryFactory.select(Projections.bean(MenuSetting.class,qMenuSetting.id,
                qMenuSetting.menuType,
                qMenuSetting.name,
                qMenuSetting.prueferId,
                qpruefer.pRVORNAME.as("prueferName"),
                qMenuSetting.name,
                qMenuSetting.order)).from(qMenuSetting).leftJoin(qpruefer).on(qpruefer.pRPRUEFER.eq(qMenuSetting.prueferId))
                .where(builder).limit(limit).offset((page-1)*limit).orderBy(qMenuSetting.order.asc()).fetch();

        return new ResultPage<MenuSetting>(list,page-1,limit,count);
    }

    public List<MenuType> getList(Integer type,Integer prueferId){
        QMenuSetting qMenuSetting = QMenuSetting.menuSetting;
        String username = JWTUtils.getToken().getUsername();
        List<MenuType> list = jpaQueryFactory.select(Projections.bean(MenuType.class,qMenuSetting.menuType.as("value"),qMenuSetting.name)).from(qMenuSetting)
                .where(qMenuSetting.type.eq(type).and(qMenuSetting.prueferId.eq(prueferId)).and(qMenuSetting.createBy.eq(username))).orderBy(qMenuSetting.order.asc()).fetch();
        return list;
    }


    public MenuSetting add(MenuSetting menuSetting){
        return this.menuSettingRepository.save(menuSetting);
    }

    public void delete(String id){
        this.menuSettingRepository.deleteById(id);
    }
}
